package com.xmutca.micro.uaa.controller;

import com.xmutca.micro.uaa.controller.vo.LoginVO;
import com.xmutca.micro.uaa.security.JwtTokenFactory;
import lombok.AllArgsConstructor;
import lombok.NonNull;
import org.springframework.http.ResponseEntity;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletRequest;

/**
 * Created by chunchengpeng on 17/7/27.
 */
@RestController
@AllArgsConstructor
@RequestMapping("/auth")
public class AuthenticationController {

    @NonNull
    private JwtTokenFactory jwtTokenFactory;

    @NonNull
    private AuthenticationManager authenticationManager;

    @NonNull
    private UserDetailsService userDetailsService;

    @RequestMapping(method = RequestMethod.POST, value = "/login")
    public ResponseEntity<?> authentication(@ModelAttribute LoginVO loginVO, HttpServletRequest request) {

        // Perform the authentication
        Authentication authentication = this.authenticationManager.authenticate(
                new UsernamePasswordAuthenticationToken(loginVO.getUsername(), loginVO.getPassword())
        );
        SecurityContextHolder.getContext().setAuthentication(authentication);

        // Reload password post-authentication so we can generate token
        UserDetails userDetails = this.userDetailsService.loadUserByUsername(loginVO.getUsername());

        // get Token
        String token = jwtTokenFactory.createToken(userDetails, request);

        // Return the token
        return ResponseEntity.ok(token);
    }
}
